Libraries

library(dplyr)
library(ggplot2)
library(targets)

Helper Functions

source("R/functions_analysis.R")

Data

tar_load(metric_table_master)

Analysis

Reference Dataset

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = ROC_AUC, y = SIM_REFERENCE, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  facet_wrap(~MODEL_TYPE) + 
  ggridges::geom_density_ridges(alpha = 0.6, scale = 0.95, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent()) + 
  labs(y = "Reference Dataset", x = "ROC-AUC") + 
  theme_analysis() + 
  theme(legend.position = "none")

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = F_MEASURE, y = SIM_REFERENCE, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  facet_wrap(~MODEL_TYPE) + 
  ggridges::geom_density_ridges(alpha = 0.6, scale = 0.95, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_number(accuracy = 0.1), 
                     limits = c(NA, 1)) + 
  labs(y = "Reference Dataset", x = "F-measure") + 
  theme_analysis() + 
  theme(legend.position = "none")

Runtime

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS), 
         RUNTIME_MINS = RUNTIME_HOURS * 60) %>% 
  ggplot(aes(x = N_CELLS, y = RUNTIME_MINS, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_number(accuracy = 1, suffix = "min")) + 
  labs(x = "Cells", y = "Runtime") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(RUNTIME_MINS = RUNTIME_HOURS * 60, 
         GENES_PER_MIN = N_GENES / RUNTIME_MINS) %>% 
  ggplot(aes(x = N_CELLS, y = GENES_PER_MIN, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_smooth(method = "lm", alpha = 0.25) + 
  scale_y_continuous(labels = scales::label_number(accuracy = 1)) + 
  labs(x = "Cells", y = "Genes per Minute") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 0, linewidth = 2)))

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(RUNTIME_MINS = RUNTIME_HOURS * 60, 
         GENES_PER_MIN = N_GENES / RUNTIME_MINS) %>% 
  ggplot(aes(x = GENES_PER_MIN, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_number(accuracy = 1)) + 
  labs(x = "Genes per Minute", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

Memory Usage

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS), 
         MEM_USED_GB = MEM_USED / 1000) %>% 
  ggplot(aes(x = N_CELLS, y = MEM_USED_GB, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_number(suffix = "gb")) + 
  labs(x = "Cells", y = "Memory Usage") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(MEM_USED_GB = MEM_USED / 1000) %>% 
  ggplot(aes(x = MEM_USED_GB, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_number(suffix = "gb")) + 
  labs(x = "Memory Usage", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

Predictive Performance

F-measure

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = F_MEASURE, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_number(accuracy = 0.1)) + 
  labs(x = "Cells", y = "F-measure") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = F_MEASURE, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_number(accuracy = 0.1)) + 
  labs(x = "F-measure", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

Balanced Accuracy

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = BAL_ACCURACY, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Cells", y = "Balanced Accuracy") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = BAL_ACCURACY, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Balanced Accuracy", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

Recall

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = RECALL, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Cells", y = "Recall") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = RECALL, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Recall", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

Accuracy

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = ACCURACY)) + 
  geom_boxplot(aes(color = MODEL_TYPE)) + 
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Cells", y = "Accuracy") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = ACCURACY, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Accuracy", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

ROC-AUC

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = ROC_AUC, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Cells", y = "ROC-AUC") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = ROC_AUC, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "ROC-AUC", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM")) %>% 
  pull(ROC_CURVE) %>% 
  purrr::reduce(rbind) %>% 
  left_join((distinct(metric_table_master, DATASET_NAME, N_CELLS)), 
            by = c("dataset" = "DATASET_NAME")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = 1 - specificity, y = sensitivity, group = dataset, color = N_CELLS)) + 
  facet_wrap(~paste0("Cells: ", N_CELLS)) + 
  geom_segment(x = 0, xend = 0, y = 1, yend = 1, color = "black", linetype = "dashed", size = 1) + 
  geom_line(size = 1, alpha = 0.8) + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) + 
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) + 
  labs(x = "1 - Specificity", 
      y = "Sensitivity", 
      color = "Cells", 
      title = "scLANE - GLM") + 
  theme_analysis() +  
  guides(color = guide_legend(override.aes = list(linewidth = 2, alpha = 1)))

filter(metric_table_master, 
       MODEL_TYPE %in% c("tradeSeq")) %>% 
  pull(ROC_CURVE) %>% 
  purrr::reduce(rbind) %>% 
  left_join((distinct(metric_table_master, DATASET_NAME, N_CELLS)), 
            by = c("dataset" = "DATASET_NAME")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = 1 - specificity, y = sensitivity, group = dataset, color = N_CELLS)) + 
  facet_wrap(~paste0("Cells: ", N_CELLS)) + 
  geom_segment(x = 0, xend = 0, y = 1, yend = 1, color = "black", linetype = "dashed", size = 1) + 
  geom_line(size = 1, alpha = 0.8) + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) + 
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) + 
  labs(x = "1 - Specificity", 
      y = "Sensitivity", 
      color = "Cells", 
      title = "tradeSeq") + 
  theme_analysis() + 
  guides(color = guide_legend(override.aes = list(linewidth = 2, alpha = 1)))

PR-AUC

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = N_CELLS, y = AUC_PR, color = MODEL_TYPE)) + 
  geom_boxplot() + 
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "Cells", y = "PR-AUC") + 
  theme_analysis() + 
  theme(legend.title = element_blank())

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM", "tradeSeq")) %>% 
  ggplot(aes(x = AUC_PR, color = MODEL_TYPE, fill = MODEL_TYPE)) + 
  geom_density(alpha = 0.3, linewidth = 1) + 
  scale_x_continuous(labels = scales::label_percent(accuracy = 1)) + 
  labs(x = "PR-AUC", y = "Density") + 
  theme_analysis() + 
  theme(legend.title = element_blank()) + 
  guides(color = guide_legend(override.aes = list(alpha = 1, color = "white", linewidth = 0.5)))

filter(metric_table_master, 
       MODEL_TYPE %in% c("scLANE - GLM")) %>% 
  pull(PR_CURVE) %>% 
  purrr::reduce(rbind) %>% 
  left_join((distinct(metric_table_master, DATASET_NAME, N_CELLS)), 
            by = c("dataset" = "DATASET_NAME")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = recall, y = precision, group = dataset, color = N_CELLS)) + 
  facet_wrap(~paste0("Cells: ", N_CELLS)) + 
  geom_segment(x = 0, xend = 1, y = 1, yend = 0, color = "black", linetype = "dashed", size = 1) + 
  geom_line(size = 1, alpha = 0.8) + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_y_continuous(limits = c(0, 1), labels = scales::percent_format(accuracy = 1)) +
  labs(x = "Recall", 
       y = "Precision", 
       color = "Cells", 
       title = "scLANE - GLM") + 
  theme_analysis() + 
  guides(color = guide_legend(override.aes = list(linewidth = 2, alpha = 1)))

filter(metric_table_master, 
       MODEL_TYPE %in% c("tradeSeq")) %>% 
  pull(PR_CURVE) %>% 
  purrr::reduce(rbind) %>% 
  left_join((distinct(metric_table_master, DATASET_NAME, N_CELLS)), 
            by = c("dataset" = "DATASET_NAME")) %>% 
  mutate(N_CELLS = round(N_CELLS, digits = -1), 
         N_CELLS = as.factor(N_CELLS)) %>% 
  ggplot(aes(x = recall, y = precision, group = dataset, color = N_CELLS)) + 
  facet_wrap(~paste0("Cells: ", N_CELLS)) + 
  geom_segment(x = 0, xend = 1, y = 1, yend = 0, color = "black", linetype = "dashed", size = 1) + 
  geom_line(size = 1, alpha = 0.8) + 
  scale_x_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_y_continuous(limits = c(0, 1), labels = scales::percent_format(accuracy = 1)) +
  labs(x = "Recall", 
       y = "Precision", 
       color = "Cells", 
       title = "tradeSeq") + 
  theme_analysis() + 
  guides(color = guide_legend(override.aes = list(linewidth = 2, alpha = 1)))

Session Info

sessioninfo::session_info()
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.2.3 (2023-03-15)
 os       Ubuntu 22.04.2 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/New_York
 date     2023-08-22
 pandoc   2.9.2.1 @ /usr/bin/ (via rmarkdown)

─ Packages ───────────────────────────────────────────────────────────────────
 package              * version    date (UTC) lib source
 backports              1.4.1      2021-12-13 [2] CRAN (R 4.2.0)
 base64url              1.4        2018-05-14 [2] CRAN (R 4.2.0)
 bigassertr             0.1.6      2023-01-10 [2] CRAN (R 4.2.2)
 bigparallelr           0.3.2      2021-10-02 [2] CRAN (R 4.2.0)
 bigstatsr              1.5.12     2022-10-14 [2] CRAN (R 4.2.2)
 Biobase              * 2.58.0     2022-11-01 [2] Bioconductor
 BiocGenerics         * 0.44.0     2023-02-01 [2] bioc_git2r (@d7cd9c1)
 BiocParallel           1.32.6     2023-03-17 [2] Bioconductor
 bitops                 1.0-7      2021-04-24 [2] CRAN (R 4.2.0)
 boot                   1.3-28.1   2022-11-22 [2] CRAN (R 4.2.2)
 broom                * 1.0.5      2023-06-09 [2] CRAN (R 4.2.3)
 broom.mixed            0.2.9.4    2022-04-17 [2] CRAN (R 4.2.0)
 bslib                  0.5.0      2023-06-09 [2] CRAN (R 4.2.3)
 cachem                 1.0.8      2023-05-01 [2] CRAN (R 4.2.3)
 callr                  3.7.3      2022-11-02 [2] CRAN (R 4.2.2)
 cellranger             1.1.0      2016-07-27 [2] CRAN (R 4.2.0)
 class                  7.3-22     2023-05-03 [4] CRAN (R 4.2.3)
 cli                    3.6.1      2023-03-23 [2] CRAN (R 4.2.3)
 coda                   0.19-4     2020-09-30 [2] CRAN (R 4.2.0)
 codetools              0.2-19     2023-02-01 [4] CRAN (R 4.2.2)
 colorspace             2.1-0      2023-01-23 [2] CRAN (R 4.2.2)
 cowplot                1.1.1      2020-12-30 [2] CRAN (R 4.2.0)
 crayon                 1.5.2      2022-09-29 [2] CRAN (R 4.2.1)
 data.table             1.14.8     2023-02-17 [2] CRAN (R 4.2.3)
 DBI                    1.1.3      2022-06-18 [2] CRAN (R 4.2.0)
 dbplyr                 2.3.3      2023-07-07 [2] CRAN (R 4.2.3)
 DelayedArray           0.24.0     2022-11-01 [2] Bioconductor
 dials                * 1.2.0      2023-04-03 [2] CRAN (R 4.2.3)
 DiceDesign             1.9        2021-02-13 [2] CRAN (R 4.2.0)
 digest                 0.6.33     2023-07-07 [1] CRAN (R 4.2.3)
 doParallel             1.0.17     2022-02-07 [2] CRAN (R 4.2.0)
 dplyr                * 1.1.2      2023-04-20 [1] CRAN (R 4.2.3)
 edgeR                  3.40.2     2023-02-01 [2] bioc_git2r (@ddb1cb9)
 emmeans                1.8.7      2023-06-23 [2] CRAN (R 4.2.3)
 estimability           1.4.1      2022-08-05 [2] CRAN (R 4.2.0)
 evaluate               0.21       2023-05-05 [2] CRAN (R 4.2.3)
 fansi                  1.0.4      2023-01-22 [2] CRAN (R 4.2.2)
 farver                 2.1.1      2022-07-06 [2] CRAN (R 4.2.0)
 fastmap                1.1.1      2023-02-24 [2] CRAN (R 4.2.3)
 flock                  0.7        2016-11-12 [2] CRAN (R 4.2.0)
 forcats              * 1.0.0      2023-01-29 [2] CRAN (R 4.2.2)
 foreach                1.5.2      2022-02-02 [1] CRAN (R 4.2.0)
 fs                     1.6.2      2023-04-25 [2] CRAN (R 4.2.3)
 furrr                  0.3.1      2022-08-15 [2] CRAN (R 4.2.0)
 future               * 1.33.0     2023-07-01 [1] CRAN (R 4.2.3)
 future.apply           1.11.0     2023-05-21 [2] CRAN (R 4.2.3)
 future.callr         * 0.8.1      2022-12-14 [1] CRAN (R 4.2.3)
 gamlss                 5.4-12     2023-01-27 [2] CRAN (R 4.2.2)
 gamlss.data            6.0-2      2021-11-07 [2] CRAN (R 4.2.0)
 gamlss.dist            6.0-5      2022-08-28 [2] CRAN (R 4.2.1)
 gargle                 1.5.1      2023-06-19 [2] CRAN (R 4.2.3)
 geeM                   0.10.1     2018-06-18 [2] CRAN (R 4.2.0)
 generics               0.1.3      2022-07-05 [1] CRAN (R 4.2.0)
 GenomeInfoDb         * 1.34.9     2023-02-02 [2] Bioconductor
 GenomeInfoDbData       1.2.9      2023-01-19 [2] Bioconductor
 GenomicRanges        * 1.50.2     2022-12-16 [2] Bioconductor
 ggplot2              * 3.4.2      2023-04-03 [1] CRAN (R 4.2.3)
 ggridges               0.5.4      2022-09-26 [2] CRAN (R 4.2.1)
 glm2                 * 1.2.1      2018-08-11 [2] CRAN (R 4.2.0)
 glmmTMB                1.1.7      2023-04-05 [1] CRAN (R 4.2.3)
 globals                0.16.2     2022-11-21 [2] CRAN (R 4.2.2)
 glue                   1.6.2      2022-02-24 [2] CRAN (R 4.2.0)
 googledrive            2.1.1      2023-06-11 [2] CRAN (R 4.2.3)
 googlesheets4          1.1.1      2023-06-11 [2] CRAN (R 4.2.3)
 gower                  1.0.1      2022-12-22 [2] CRAN (R 4.2.2)
 GPfit                  1.0-8      2019-02-08 [2] CRAN (R 4.2.0)
 gridExtra              2.3        2017-09-09 [2] CRAN (R 4.2.0)
 gtable                 0.3.3      2023-03-21 [2] CRAN (R 4.2.3)
 hardhat                1.3.0      2023-03-30 [2] CRAN (R 4.2.3)
 haven                  2.5.3      2023-06-30 [2] CRAN (R 4.2.3)
 highr                  0.10       2022-12-22 [2] CRAN (R 4.2.2)
 hms                    1.1.3      2023-03-21 [2] CRAN (R 4.2.3)
 htmltools              0.5.4      2022-12-07 [1] CRAN (R 4.2.2)
 httr                   1.4.6      2023-05-08 [2] CRAN (R 4.2.3)
 igraph                 1.4.1      2023-02-24 [1] CRAN (R 4.2.2)
 infer                * 1.0.4      2022-12-02 [2] CRAN (R 4.2.2)
 ipred                  0.9-14     2023-03-09 [2] CRAN (R 4.2.3)
 IRanges              * 2.32.0     2022-11-01 [2] Bioconductor
 iterators              1.0.14     2022-02-05 [2] CRAN (R 4.2.0)
 jquerylib              0.1.4      2021-04-26 [2] CRAN (R 4.2.0)
 jsonlite               1.8.7      2023-06-29 [1] CRAN (R 4.2.3)
 knitr                  1.43       2023-05-25 [2] CRAN (R 4.2.3)
 labeling               0.4.2      2020-10-20 [2] CRAN (R 4.2.0)
 lattice                0.21-8     2023-04-05 [4] CRAN (R 4.2.3)
 lava                   1.7.2.1    2023-02-27 [2] CRAN (R 4.2.3)
 lhs                    1.1.6      2022-12-17 [2] CRAN (R 4.2.2)
 lifecycle              1.0.3      2022-10-07 [2] CRAN (R 4.2.1)
 limma                  3.54.2     2023-02-28 [2] Bioconductor
 listenv                0.9.0      2022-12-16 [2] CRAN (R 4.2.2)
 lme4                   1.1-34     2023-07-04 [2] CRAN (R 4.2.3)
 locfit                 1.5-9.8    2023-06-11 [2] CRAN (R 4.2.3)
 lubridate              1.9.2      2023-02-10 [2] CRAN (R 4.2.3)
 magrittr             * 2.0.3      2022-03-30 [1] CRAN (R 4.2.0)
 MASS                   7.3-60     2023-05-04 [4] CRAN (R 4.2.3)
 Matrix                 1.6-0      2023-07-08 [2] CRAN (R 4.2.3)
 MatrixGenerics       * 1.10.0     2022-11-01 [2] Bioconductor
 matrixStats          * 1.0.0      2023-06-02 [2] CRAN (R 4.2.3)
 mgcv                   1.9-0      2023-07-11 [4] CRAN (R 4.2.3)
 minqa                  1.2.5      2022-10-19 [2] CRAN (R 4.2.2)
 modeldata            * 1.1.0      2023-01-25 [2] CRAN (R 4.2.3)
 modelr                 0.1.11     2023-03-22 [2] CRAN (R 4.2.3)
 multcomp               1.4-25     2023-06-20 [2] CRAN (R 4.2.3)
 munsell                0.5.0      2018-06-12 [2] CRAN (R 4.2.0)
 mvtnorm                1.2-2      2023-06-08 [2] CRAN (R 4.2.3)
 nanonext               0.9.1      2023-07-13 [1] CRAN (R 4.2.3)
 nlme                   3.1-162    2023-01-31 [2] CRAN (R 4.2.3)
 nloptr                 2.0.3      2022-05-26 [2] CRAN (R 4.2.0)
 nnet                   7.3-18     2022-09-28 [1] CRAN (R 4.2.2)
 numDeriv               2016.8-1.1 2019-06-06 [2] CRAN (R 4.2.0)
 parallelly             1.36.0     2023-05-26 [2] CRAN (R 4.2.3)
 parsnip              * 1.0.3      2022-11-11 [1] CRAN (R 4.2.2)
 pbapply                1.7-2      2023-06-27 [2] CRAN (R 4.2.3)
 pillar                 1.9.0      2023-03-22 [2] CRAN (R 4.2.3)
 pkgconfig              2.0.3      2019-09-22 [2] CRAN (R 4.2.0)
 princurve              2.1.6      2021-01-18 [2] CRAN (R 4.2.0)
 processx               3.8.2      2023-06-30 [2] CRAN (R 4.2.3)
 prodlim                2023.03.31 2023-04-02 [2] CRAN (R 4.2.3)
 ps                     1.7.5      2023-04-18 [2] CRAN (R 4.2.3)
 purrr                * 1.0.1      2023-01-10 [1] CRAN (R 4.2.3)
 qs                   * 0.25.4     2022-08-09 [1] CRAN (R 4.2.0)
 R6                     2.5.1      2021-08-19 [2] CRAN (R 4.2.0)
 RApiSerialize          0.1.2      2022-08-25 [1] CRAN (R 4.2.0)
 RColorBrewer           1.1-3      2022-04-03 [2] CRAN (R 4.2.0)
 Rcpp                   1.0.11     2023-07-06 [2] CRAN (R 4.2.3)
 RcppEigen              0.3.3.9.3  2022-11-05 [2] CRAN (R 4.2.2)
 RcppParallel           5.1.7      2023-02-27 [2] CRAN (R 4.2.3)
 RCurl                  1.98-1.12  2023-03-27 [2] CRAN (R 4.2.3)
 readr                * 2.1.4      2023-02-10 [2] CRAN (R 4.2.3)
 readxl                 1.4.3      2023-07-06 [2] CRAN (R 4.2.3)
 recipes              * 1.0.4      2023-01-11 [1] CRAN (R 4.2.2)
 reprex                 2.0.2      2022-08-17 [2] CRAN (R 4.2.1)
 rlang                  1.1.1      2023-04-28 [1] CRAN (R 4.2.3)
 rmarkdown            * 2.20       2023-01-19 [1] CRAN (R 4.2.2)
 rpart                  4.1.19     2022-10-21 [4] CRAN (R 4.2.1)
 rsample              * 1.1.1      2022-12-07 [2] CRAN (R 4.2.2)
 rstudioapi             0.14       2022-08-22 [1] CRAN (R 4.2.0)
 rvest                  1.0.3      2022-08-19 [2] CRAN (R 4.2.1)
 S4Vectors            * 0.36.2     2023-02-26 [2] Bioconductor
 sandwich               3.0-2      2022-06-15 [1] CRAN (R 4.2.0)
 sass                   0.4.4      2022-11-24 [1] CRAN (R 4.2.2)
 scales               * 1.2.1      2022-08-20 [2] CRAN (R 4.2.1)
 scLANE               * 0.7.1      2023-07-15 [1] Github (jr-leary7/scLANE@248b944)
 sessioninfo            1.2.2      2021-12-06 [2] CRAN (R 4.2.0)
 SingleCellExperiment * 1.20.1     2023-03-17 [2] Bioconductor
 slingshot              2.4.0      2022-04-26 [1] Bioconductor
 stringfish             0.15.7     2022-04-13 [1] CRAN (R 4.2.0)
 stringi                1.7.12     2023-01-11 [2] CRAN (R 4.2.2)
 stringr              * 1.5.0      2022-12-02 [2] CRAN (R 4.2.2)
 SummarizedExperiment * 1.28.0     2023-02-01 [2] bioc_git2r (@ba55dac)
 survival               3.5-5      2023-03-12 [2] CRAN (R 4.2.3)
 tarchetypes          * 0.7.7      2023-06-15 [1] CRAN (R 4.2.3)
 targets              * 1.2.0      2023-06-26 [1] CRAN (R 4.2.3)
 TH.data                1.1-2      2023-04-17 [2] CRAN (R 4.2.3)
 tibble               * 3.2.1      2023-03-20 [2] CRAN (R 4.2.3)
 tidymodels           * 1.0.0      2022-07-13 [1] CRAN (R 4.2.0)
 tidyr                * 1.3.0      2023-01-24 [2] CRAN (R 4.2.2)
 tidyselect             1.2.0      2022-10-10 [2] CRAN (R 4.2.1)
 tidyverse            * 1.3.2      2022-07-18 [1] CRAN (R 4.2.0)
 timechange             0.2.0      2023-01-11 [2] CRAN (R 4.2.2)
 timeDate               4022.108   2023-01-07 [2] CRAN (R 4.2.2)
 TMB                    1.9.4      2023-04-18 [1] CRAN (R 4.2.3)
 tradeSeq             * 1.10.0     2022-04-26 [1] Bioconductor
 TrajectoryUtils        1.4.0      2022-04-26 [1] Bioconductor
 tune                 * 1.1.1      2023-04-11 [2] CRAN (R 4.2.3)
 tzdb                   0.4.0      2023-05-12 [2] CRAN (R 4.2.3)
 utf8                   1.2.3      2023-01-31 [2] CRAN (R 4.2.2)
 vctrs                  0.6.3      2023-06-14 [2] CRAN (R 4.2.3)
 viridis                0.6.3      2023-05-03 [2] CRAN (R 4.2.3)
 viridisLite            0.4.2      2023-05-02 [2] CRAN (R 4.2.3)
 withr                  2.5.0      2022-03-03 [2] CRAN (R 4.2.0)
 workflows            * 1.1.3      2023-02-22 [2] CRAN (R 4.2.3)
 workflowsets         * 1.0.0      2022-07-12 [1] CRAN (R 4.2.0)
 xfun                   0.39       2023-04-20 [2] CRAN (R 4.2.3)
 xml2                   1.3.5      2023-07-06 [2] CRAN (R 4.2.3)
 xtable                 1.8-4      2019-04-21 [2] CRAN (R 4.2.0)
 XVector                0.38.0     2022-11-01 [2] Bioconductor
 yaml                   2.3.7      2023-01-23 [2] CRAN (R 4.2.2)
 yardstick            * 1.2.0      2023-04-21 [2] CRAN (R 4.2.3)
 zlibbioc               1.44.0     2022-11-01 [2] Bioconductor
 zoo                    1.8-12     2023-04-13 [2] CRAN (R 4.2.3)

 [1] /home/j.leary/r_packages_default
 [2] /usr/local/lib/R/site-library
 [3] /usr/lib/R/site-library
 [4] /usr/lib/R/library

──────────────────────────────────────────────────────────────────────────────
LS0tCnRpdGxlOiAiYHNjTEFORWAgU2ltdWxhdGlvbiBTdHVkeSAtIFRyYWplY3RvcnkgREUgTWV0aG9kIENvbXBhcmlzb24iCnN1YnRpdGxlOiAiVUYgRGVwdC4gb2YgQmlvc3RhdGlzdGljcyAtIEJhY2hlciBHcm91cCIKYXV0aG9yOiAiSmFjayBMZWFyeSIgCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogam91cm5hbAogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlIAogICAgdG9jOiB0cnVlIAogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGRmX3ByaW50OiBrYWJsZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBjb21tZW50ID0gTkEsIGRldiA9ICJwbmciLCBkcGkgPSAzMjApCmBgYAoKIyBMaWJyYXJpZXMgCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRhcmdldHMpCmBgYAoKIyBIZWxwZXIgRnVuY3Rpb25zCgpgYGB7cn0Kc291cmNlKCJSL2Z1bmN0aW9uc19hbmFseXNpcy5SIikKYGBgCgojIERhdGEKCmBgYHtyfQp0YXJfbG9hZChtZXRyaWNfdGFibGVfbWFzdGVyKQpgYGAKCiMgQW5hbHlzaXMKCiMjIFJlZmVyZW5jZSBEYXRhc2V0CgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gUk9DX0FVQywgeSA9IFNJTV9SRUZFUkVOQ0UsIGNvbG9yID0gTU9ERUxfVFlQRSwgZmlsbCA9IE1PREVMX1RZUEUpKSArIAogIGZhY2V0X3dyYXAofk1PREVMX1RZUEUpICsgCiAgZ2dyaWRnZXM6Omdlb21fZGVuc2l0eV9yaWRnZXMoYWxwaGEgPSAwLjYsIHNjYWxlID0gMC45NSwgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KCkpICsgCiAgbGFicyh5ID0gIlJlZmVyZW5jZSBEYXRhc2V0IiwgeCA9ICJST0MtQVVDIikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyfQpmaWx0ZXIobWV0cmljX3RhYmxlX21hc3RlciwgCiAgICAgICBNT0RFTF9UWVBFICVpbiUgYygic2NMQU5FIC0gR0xNIiwgInRyYWRlU2VxIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBGX01FQVNVUkUsIHkgPSBTSU1fUkVGRVJFTkNFLCBjb2xvciA9IE1PREVMX1RZUEUsIGZpbGwgPSBNT0RFTF9UWVBFKSkgKyAKICBmYWNldF93cmFwKH5NT0RFTF9UWVBFKSArIAogIGdncmlkZ2VzOjpnZW9tX2RlbnNpdHlfcmlkZ2VzKGFscGhhID0gMC42LCBzY2FsZSA9IDAuOTUsIGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbnVtYmVyKGFjY3VyYWN5ID0gMC4xKSwgCiAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoTkEsIDEpKSArIAogIGxhYnMoeSA9ICJSZWZlcmVuY2UgRGF0YXNldCIsIHggPSAiRi1tZWFzdXJlIikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCiMjIFJ1bnRpbWUKCmBgYHtyfQpmaWx0ZXIobWV0cmljX3RhYmxlX21hc3RlciwgCiAgICAgICBNT0RFTF9UWVBFICVpbiUgYygic2NMQU5FIC0gR0xNIiwgInRyYWRlU2VxIikpICU+JSAKICBtdXRhdGUoTl9DRUxMUyA9IHJvdW5kKE5fQ0VMTFMsIGRpZ2l0cyA9IC0xKSwgCiAgICAgICAgIE5fQ0VMTFMgPSBhcy5mYWN0b3IoTl9DRUxMUyksIAogICAgICAgICBSVU5USU1FX01JTlMgPSBSVU5USU1FX0hPVVJTICogNjApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBOX0NFTExTLCB5ID0gUlVOVElNRV9NSU5TLCBjb2xvciA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbnVtYmVyKGFjY3VyYWN5ID0gMSwgc3VmZml4ID0gIm1pbiIpKSArIAogIGxhYnMoeCA9ICJDZWxscyIsIHkgPSAiUnVudGltZSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgbXV0YXRlKFJVTlRJTUVfTUlOUyA9IFJVTlRJTUVfSE9VUlMgKiA2MCwgCiAgICAgICAgIEdFTkVTX1BFUl9NSU4gPSBOX0dFTkVTIC8gUlVOVElNRV9NSU5TKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gTl9DRUxMUywgeSA9IEdFTkVTX1BFUl9NSU4sIGNvbG9yID0gTU9ERUxfVFlQRSwgZmlsbCA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGFscGhhID0gMC4yNSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoYWNjdXJhY3kgPSAxKSkgKyAKICBsYWJzKHggPSAiQ2VsbHMiLCB5ID0gIkdlbmVzIHBlciBNaW51dGUiKSArIAogIHRoZW1lX2FuYWx5c2lzKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAwLCBsaW5ld2lkdGggPSAyKSkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIG11dGF0ZShSVU5USU1FX01JTlMgPSBSVU5USU1FX0hPVVJTICogNjAsIAogICAgICAgICBHRU5FU19QRVJfTUlOID0gTl9HRU5FUyAvIFJVTlRJTUVfTUlOUykgJT4lIAogIGdncGxvdChhZXMoeCA9IEdFTkVTX1BFUl9NSU4sIGNvbG9yID0gTU9ERUxfVFlQRSwgZmlsbCA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuMywgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoYWNjdXJhY3kgPSAxKSkgKyAKICBsYWJzKHggPSAiR2VuZXMgcGVyIE1pbnV0ZSIsIHkgPSAiRGVuc2l0eSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC41KSkpCmBgYAoKIyMgTWVtb3J5IFVzYWdlCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgbXV0YXRlKE5fQ0VMTFMgPSByb3VuZChOX0NFTExTLCBkaWdpdHMgPSAtMSksIAogICAgICAgICBOX0NFTExTID0gYXMuZmFjdG9yKE5fQ0VMTFMpLCAKICAgICAgICAgTUVNX1VTRURfR0IgPSBNRU1fVVNFRCAvIDEwMDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBOX0NFTExTLCB5ID0gTUVNX1VTRURfR0IsIGNvbG9yID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoc3VmZml4ID0gImdiIikpICsgCiAgbGFicyh4ID0gIkNlbGxzIiwgeSA9ICJNZW1vcnkgVXNhZ2UiKSArIAogIHRoZW1lX2FuYWx5c2lzKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIG11dGF0ZShNRU1fVVNFRF9HQiA9IE1FTV9VU0VEIC8gMTAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IE1FTV9VU0VEX0dCLCBjb2xvciA9IE1PREVMX1RZUEUsIGZpbGwgPSBNT0RFTF9UWVBFKSkgKyAKICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjMsIGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbnVtYmVyKHN1ZmZpeCA9ICJnYiIpKSArIAogIGxhYnMoeCA9ICJNZW1vcnkgVXNhZ2UiLCB5ID0gIkRlbnNpdHkiKSArIAogIHRoZW1lX2FuYWx5c2lzKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxLCBjb2xvciA9ICJ3aGl0ZSIsIGxpbmV3aWR0aCA9IDAuNSkpKQpgYGAKCiMjIFByZWRpY3RpdmUgUGVyZm9ybWFuY2UKCiMjIyBGLW1lYXN1cmUgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgbXV0YXRlKE5fQ0VMTFMgPSByb3VuZChOX0NFTExTLCBkaWdpdHMgPSAtMSksIAogICAgICAgICBOX0NFTExTID0gYXMuZmFjdG9yKE5fQ0VMTFMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gTl9DRUxMUywgeSA9IEZfTUVBU1VSRSwgY29sb3IgPSBNT0RFTF9UWVBFKSkgKyAKICBnZW9tX2JveHBsb3QoKSArIAogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX251bWJlcihhY2N1cmFjeSA9IDAuMSkpICsgCiAgbGFicyh4ID0gIkNlbGxzIiwgeSA9ICJGLW1lYXN1cmUiKSArIAogIHRoZW1lX2FuYWx5c2lzKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IEZfTUVBU1VSRSwgY29sb3IgPSBNT0RFTF9UWVBFLCBmaWxsID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4zLCBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX251bWJlcihhY2N1cmFjeSA9IDAuMSkpICsgCiAgbGFicyh4ID0gIkYtbWVhc3VyZSIsIHkgPSAiRGVuc2l0eSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC41KSkpCmBgYAoKIyMjIEJhbGFuY2VkIEFjY3VyYWN5IAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIG11dGF0ZShOX0NFTExTID0gcm91bmQoTl9DRUxMUywgZGlnaXRzID0gLTEpLCAKICAgICAgICAgTl9DRUxMUyA9IGFzLmZhY3RvcihOX0NFTExTKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IE5fQ0VMTFMsIHkgPSBCQUxfQUNDVVJBQ1ksIGNvbG9yID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIkNlbGxzIiwgeSA9ICJCYWxhbmNlZCBBY2N1cmFjeSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gQkFMX0FDQ1VSQUNZLCBjb2xvciA9IE1PREVMX1RZUEUsIGZpbGwgPSBNT0RFTF9UWVBFKSkgKyAKICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjMsIGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfcGVyY2VudChhY2N1cmFjeSA9IDEpKSArIAogIGxhYnMoeCA9ICJCYWxhbmNlZCBBY2N1cmFjeSIsIHkgPSAiRGVuc2l0eSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC41KSkpCmBgYAoKIyMjIFJlY2FsbAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIG11dGF0ZShOX0NFTExTID0gcm91bmQoTl9DRUxMUywgZGlnaXRzID0gLTEpLCAKICAgICAgICAgTl9DRUxMUyA9IGFzLmZhY3RvcihOX0NFTExTKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IE5fQ0VMTFMsIHkgPSBSRUNBTEwsIGNvbG9yID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIkNlbGxzIiwgeSA9ICJSZWNhbGwiKSArIAogIHRoZW1lX2FuYWx5c2lzKCkgKyAKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFJFQ0FMTCwgY29sb3IgPSBNT0RFTF9UWVBFLCBmaWxsID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4zLCBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX3BlcmNlbnQoYWNjdXJhY3kgPSAxKSkgKyAKICBsYWJzKHggPSAiUmVjYWxsIiwgeSA9ICJEZW5zaXR5IikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSwgY29sb3IgPSAid2hpdGUiLCBsaW5ld2lkdGggPSAwLjUpKSkKYGBgCgojIyMgQWNjdXJhY3kKCmBgYHtyfQpmaWx0ZXIobWV0cmljX3RhYmxlX21hc3RlciwgCiAgICAgICBNT0RFTF9UWVBFICVpbiUgYygic2NMQU5FIC0gR0xNIiwgInRyYWRlU2VxIikpICU+JSAKICBtdXRhdGUoTl9DRUxMUyA9IHJvdW5kKE5fQ0VMTFMsIGRpZ2l0cyA9IC0xKSwgCiAgICAgICAgIE5fQ0VMTFMgPSBhcy5mYWN0b3IoTl9DRUxMUykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBOX0NFTExTLCB5ID0gQUNDVVJBQ1kpKSArIAogIGdlb21fYm94cGxvdChhZXMoY29sb3IgPSBNT0RFTF9UWVBFKSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIkNlbGxzIiwgeSA9ICJBY2N1cmFjeSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gQUNDVVJBQ1ksIGNvbG9yID0gTU9ERUxfVFlQRSwgZmlsbCA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuMywgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIkFjY3VyYWN5IiwgeSA9ICJEZW5zaXR5IikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSwgY29sb3IgPSAid2hpdGUiLCBsaW5ld2lkdGggPSAwLjUpKSkKYGBgCgojIyMgUk9DLUFVQwoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iLCAidHJhZGVTZXEiKSkgJT4lIAogIG11dGF0ZShOX0NFTExTID0gcm91bmQoTl9DRUxMUywgZGlnaXRzID0gLTEpLCAKICAgICAgICAgTl9DRUxMUyA9IGFzLmZhY3RvcihOX0NFTExTKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IE5fQ0VMTFMsIHkgPSBST0NfQVVDLCBjb2xvciA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfcGVyY2VudChhY2N1cmFjeSA9IDEpKSArIAogIGxhYnMoeCA9ICJDZWxscyIsIHkgPSAiUk9DLUFVQyIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInNjTEFORSAtIEdMTSIsICJ0cmFkZVNlcSIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gUk9DX0FVQywgY29sb3IgPSBNT0RFTF9UWVBFLCBmaWxsID0gTU9ERUxfVFlQRSkpICsgCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4zLCBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX3BlcmNlbnQoYWNjdXJhY3kgPSAxKSkgKyAKICBsYWJzKHggPSAiUk9DLUFVQyIsIHkgPSAiRGVuc2l0eSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC41KSkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iKSkgJT4lIAogIHB1bGwoUk9DX0NVUlZFKSAlPiUgCiAgcHVycnI6OnJlZHVjZShyYmluZCkgJT4lIAogIGxlZnRfam9pbigoZGlzdGluY3QobWV0cmljX3RhYmxlX21hc3RlciwgREFUQVNFVF9OQU1FLCBOX0NFTExTKSksIAogICAgICAgICAgICBieSA9IGMoImRhdGFzZXQiID0gIkRBVEFTRVRfTkFNRSIpKSAlPiUgCiAgbXV0YXRlKE5fQ0VMTFMgPSByb3VuZChOX0NFTExTLCBkaWdpdHMgPSAtMSksIAogICAgICAgICBOX0NFTExTID0gYXMuZmFjdG9yKE5fQ0VMTFMpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gMSAtIHNwZWNpZmljaXR5LCB5ID0gc2Vuc2l0aXZpdHksIGdyb3VwID0gZGF0YXNldCwgY29sb3IgPSBOX0NFTExTKSkgKyAKICBmYWNldF93cmFwKH5wYXN0ZTAoIkNlbGxzOiAiLCBOX0NFTExTKSkgKyAKICBnZW9tX3NlZ21lbnQoeCA9IDAsIHhlbmQgPSAwLCB5ID0gMSwgeWVuZCA9IDEsIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsgCiAgZ2VvbV9saW5lKHNpemUgPSAxLCBhbHBoYSA9IDAuOCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArIAogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIjEgLSBTcGVjaWZpY2l0eSIsIAogICAgICB5ID0gIlNlbnNpdGl2aXR5IiwgCiAgICAgIGNvbG9yID0gIkNlbGxzIiwgCiAgICAgIHRpdGxlID0gInNjTEFORSAtIEdMTSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArICAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChsaW5ld2lkdGggPSAyLCBhbHBoYSA9IDEpKSkKYGBgCgpgYGB7cn0KZmlsdGVyKG1ldHJpY190YWJsZV9tYXN0ZXIsIAogICAgICAgTU9ERUxfVFlQRSAlaW4lIGMoInRyYWRlU2VxIikpICU+JSAKICBwdWxsKFJPQ19DVVJWRSkgJT4lIAogIHB1cnJyOjpyZWR1Y2UocmJpbmQpICU+JSAKICBsZWZ0X2pvaW4oKGRpc3RpbmN0KG1ldHJpY190YWJsZV9tYXN0ZXIsIERBVEFTRVRfTkFNRSwgTl9DRUxMUykpLCAKICAgICAgICAgICAgYnkgPSBjKCJkYXRhc2V0IiA9ICJEQVRBU0VUX05BTUUiKSkgJT4lIAogIG11dGF0ZShOX0NFTExTID0gcm91bmQoTl9DRUxMUywgZGlnaXRzID0gLTEpLCAKICAgICAgICAgTl9DRUxMUyA9IGFzLmZhY3RvcihOX0NFTExTKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IDEgLSBzcGVjaWZpY2l0eSwgeSA9IHNlbnNpdGl2aXR5LCBncm91cCA9IGRhdGFzZXQsIGNvbG9yID0gTl9DRUxMUykpICsgCiAgZmFjZXRfd3JhcCh+cGFzdGUwKCJDZWxsczogIiwgTl9DRUxMUykpICsgCiAgZ2VvbV9zZWdtZW50KHggPSAwLCB4ZW5kID0gMCwgeSA9IDEsIHllbmQgPSAxLCBjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIsIHNpemUgPSAxKSArIAogIGdlb21fbGluZShzaXplID0gMSwgYWxwaGEgPSAwLjgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArIAogIGxhYnMoeCA9ICIxIC0gU3BlY2lmaWNpdHkiLCAKICAgICAgeSA9ICJTZW5zaXRpdml0eSIsIAogICAgICBjb2xvciA9ICJDZWxscyIsIAogICAgICB0aXRsZSA9ICJ0cmFkZVNlcSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGxpbmV3aWR0aCA9IDIsIGFscGhhID0gMSkpKQpgYGAKCiMjIyBQUi1BVUMKCmBgYHtyfQpmaWx0ZXIobWV0cmljX3RhYmxlX21hc3RlciwgCiAgICAgICBNT0RFTF9UWVBFICVpbiUgYygic2NMQU5FIC0gR0xNIiwgInRyYWRlU2VxIikpICU+JSAKICBtdXRhdGUoTl9DRUxMUyA9IHJvdW5kKE5fQ0VMTFMsIGRpZ2l0cyA9IC0xKSwgCiAgICAgICAgIE5fQ0VMTFMgPSBhcy5mYWN0b3IoTl9DRUxMUykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBOX0NFTExTLCB5ID0gQVVDX1BSLCBjb2xvciA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fYm94cGxvdCgpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfcGVyY2VudChhY2N1cmFjeSA9IDEpKSArIAogIGxhYnMoeCA9ICJDZWxscyIsIHkgPSAiUFItQVVDIikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyfQpmaWx0ZXIobWV0cmljX3RhYmxlX21hc3RlciwgCiAgICAgICBNT0RFTF9UWVBFICVpbiUgYygic2NMQU5FIC0gR0xNIiwgInRyYWRlU2VxIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBBVUNfUFIsIGNvbG9yID0gTU9ERUxfVFlQRSwgZmlsbCA9IE1PREVMX1RZUEUpKSArIAogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuMywgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9wZXJjZW50KGFjY3VyYWN5ID0gMSkpICsgCiAgbGFicyh4ID0gIlBSLUFVQyIsIHkgPSAiRGVuc2l0eSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChhbHBoYSA9IDEsIGNvbG9yID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC41KSkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJzY0xBTkUgLSBHTE0iKSkgJT4lIAogIHB1bGwoUFJfQ1VSVkUpICU+JSAKICBwdXJycjo6cmVkdWNlKHJiaW5kKSAlPiUgCiAgbGVmdF9qb2luKChkaXN0aW5jdChtZXRyaWNfdGFibGVfbWFzdGVyLCBEQVRBU0VUX05BTUUsIE5fQ0VMTFMpKSwgCiAgICAgICAgICAgIGJ5ID0gYygiZGF0YXNldCIgPSAiREFUQVNFVF9OQU1FIikpICU+JSAKICBtdXRhdGUoTl9DRUxMUyA9IHJvdW5kKE5fQ0VMTFMsIGRpZ2l0cyA9IC0xKSwgCiAgICAgICAgIE5fQ0VMTFMgPSBhcy5mYWN0b3IoTl9DRUxMUykpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWNhbGwsIHkgPSBwcmVjaXNpb24sIGdyb3VwID0gZGF0YXNldCwgY29sb3IgPSBOX0NFTExTKSkgKyAKICBmYWNldF93cmFwKH5wYXN0ZTAoIkNlbGxzOiAiLCBOX0NFTExTKSkgKyAKICBnZW9tX3NlZ21lbnQoeCA9IDAsIHhlbmQgPSAxLCB5ID0gMSwgeWVuZCA9IDAsIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgc2l6ZSA9IDEpICsgCiAgZ2VvbV9saW5lKHNpemUgPSAxLCBhbHBoYSA9IDAuOCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMSksIGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIGxhYnMoeCA9ICJSZWNhbGwiLCAKICAgICAgIHkgPSAiUHJlY2lzaW9uIiwgCiAgICAgICBjb2xvciA9ICJDZWxscyIsIAogICAgICAgdGl0bGUgPSAic2NMQU5FIC0gR0xNIikgKyAKICB0aGVtZV9hbmFseXNpcygpICsgCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QobGluZXdpZHRoID0gMiwgYWxwaGEgPSAxKSkpCmBgYAoKYGBge3J9CmZpbHRlcihtZXRyaWNfdGFibGVfbWFzdGVyLCAKICAgICAgIE1PREVMX1RZUEUgJWluJSBjKCJ0cmFkZVNlcSIpKSAlPiUgCiAgcHVsbChQUl9DVVJWRSkgJT4lIAogIHB1cnJyOjpyZWR1Y2UocmJpbmQpICU+JSAKICBsZWZ0X2pvaW4oKGRpc3RpbmN0KG1ldHJpY190YWJsZV9tYXN0ZXIsIERBVEFTRVRfTkFNRSwgTl9DRUxMUykpLCAKICAgICAgICAgICAgYnkgPSBjKCJkYXRhc2V0IiA9ICJEQVRBU0VUX05BTUUiKSkgJT4lIAogIG11dGF0ZShOX0NFTExTID0gcm91bmQoTl9DRUxMUywgZGlnaXRzID0gLTEpLCAKICAgICAgICAgTl9DRUxMUyA9IGFzLmZhY3RvcihOX0NFTExTKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHJlY2FsbCwgeSA9IHByZWNpc2lvbiwgZ3JvdXAgPSBkYXRhc2V0LCBjb2xvciA9IE5fQ0VMTFMpKSArIAogIGZhY2V0X3dyYXAofnBhc3RlMCgiQ2VsbHM6ICIsIE5fQ0VMTFMpKSArIAogIGdlb21fc2VnbWVudCh4ID0gMCwgeGVuZCA9IDEsIHkgPSAxLCB5ZW5kID0gMCwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBzaXplID0gMSkgKyAKICBnZW9tX2xpbmUoc2l6ZSA9IDEsIGFscGhhID0gMC44KSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxKSwgbGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgbGFicyh4ID0gIlJlY2FsbCIsIAogICAgICAgeSA9ICJQcmVjaXNpb24iLCAKICAgICAgIGNvbG9yID0gIkNlbGxzIiwgCiAgICAgICB0aXRsZSA9ICJ0cmFkZVNlcSIpICsgCiAgdGhlbWVfYW5hbHlzaXMoKSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGxpbmV3aWR0aCA9IDIsIGFscGhhID0gMSkpKQpgYGAKCiMgU2Vzc2lvbiBJbmZvCgpgYGB7cn0Kc2Vzc2lvbmluZm86OnNlc3Npb25faW5mbygpCmBgYAo=